<?php
namespace TwinPeaks\Core;

abstract class CFrontController
{
	use TSingleton, TAppInjector;

	/**
	 * @var 
	 */
	protected $requestURI;
	
	/**
	 * @var array
	 */
	private $rules = [];
	
	/**
	 * @return void
	 */
	abstract protected function defineRules();

	/**
	 * @return CReponse
	 */
	final function getResponse()
	{
		return self::getApplication()->getResponse();
	}

	/**
	 * @return void
	 */
	protected function onCreate()
	{
		$this->defineRules();
	}

	/**
	 * Being called when front controller is selected for the request handling
	 * 
	 * @return void
	 */
	function onSelect()
	{
		// ...
	}
	
	/**
	 * Being called after rule has been executed
	 * 
	 * @return void
	 */
	function onRuleExecuted(&$result)
	{
		// ...
	}
	
	/**
	 * Being called when no rule is matched
	 * 
	 * @return CRule|false
	 */
	function onNoRuleMatched()
	{
		return false;
	}

	/**
	 * @access public
	 * @return CRule
	 */
	final function addRule($rule)
	{
		$this->rules[] = $rule;		
		return $rule;
	}
	
	/**
	 * @return CFilter
	 */
	function getFilter()
	{
		return CFilter::getInstance($this);
	}	
	
	/**
	 * @final
	 * @return CRule|null
	 */
	final function getRuleByURI($uri)
	{
		foreach ($this->getRules() as $rule)
		{
			$result = $rule->checkCondition($uri);
			if ($result)
				return $rule;
		}
		
		return null;
	}
	
	/**
	 * Returns a rule by its identifier.
	 * 
	 * @param integer $ruleId Rule ID.
	 * @return CRule
	 */
	final function getRuleById($ruleId)
	{
		foreach ($this->getRules() as $rule)
		{
			if ($rule->getId() === $ruleId)
				return $rule;
		}
		return $rule;
	}
	
	/**
	 * Returns rules.
	 * 
	 * @final
	 * @return array
	 */
	final function getRules()
	{
		return $this->rules;
	}
	
	/**
	 * @return CLayout|false
	 */
	function createPageLayout()
	{
		return null;
	}
	
	/**
	 * @return boolean
	 */
	function checkUserRights($rule = null)
	{
		return true;
	}
}
